  import fs from 'fs-extra';
  
  export class DeepSeekHash {
    // 使用下划线前缀表示私有属性
    wasmInstance = null;
    offset = 0;
    cachedUint8Memory = null;
    cachedTextEncoder = new TextEncoder();
  
    // 编码字符串到 WASM 内存
    encodeString(
      text, 
      allocate, 
      reallocate
    ) {
      // 简单情况：当没有 reallocate 函数时，直接编码整个字符串
      if (!reallocate) {
        const encoded = this.cachedTextEncoder.encode(text);
        const ptr = allocate(encoded.length, 1) >>> 0;
        const memory = this.getCachedUint8Memory();
        memory.subarray(ptr, ptr + encoded.length).set(encoded);
        this.offset = encoded.length;
        return ptr;
      }
  
      // 复杂情况：分两步处理 ASCII 和非 ASCII 字符
      const strLength = text.length;
      let ptr = allocate(strLength, 1) >>> 0;
      const memory = this.getCachedUint8Memory();
      let asciiLength = 0;
  
      // 首先尝试 ASCII 编码
      for (; asciiLength < strLength; asciiLength++) {
        const charCode = text.charCodeAt(asciiLength);
        if (charCode > 127) break;
        memory[ptr + asciiLength] = charCode;
      }
  
      // 如果存在非 ASCII 字符，需要重新分配空间并处理
      if (asciiLength !== strLength) {
        if (asciiLength > 0) {
          text = text.slice(asciiLength);
        }
        
        // 为非 ASCII 字符重新分配空间（每个字符最多需要 3 字节）
        ptr = reallocate(ptr, strLength, asciiLength + text.length * 3, 1) >>> 0;
        
        // 使用 encodeInto 处理剩余的非 ASCII 字符
        const result = this.cachedTextEncoder.encodeInto(
          text, 
          this.getCachedUint8Memory().subarray(ptr + asciiLength, ptr + asciiLength + text.length * 3)
        );
        asciiLength += result.written;
        
        // 最终调整内存大小
        ptr = reallocate(ptr, asciiLength + text.length * 3, asciiLength, 1) >>> 0;
      }
  
      this.offset = asciiLength;
      return ptr;
    }
  
    // 获取 WASM 内存视图
    getCachedUint8Memory() {
      if (this.cachedUint8Memory === null || this.cachedUint8Memory.byteLength === 0) {
        this.cachedUint8Memory = new Uint8Array(this.wasmInstance.memory.buffer);
      }
      return this.cachedUint8Memory;
    }
  
    // DeepSeekHash 计算函数
    calculateHash(
      algorithm,
      challenge,
      salt,
      difficulty,
      expireAt
    ) {
      if (algorithm !== 'DeepSeekHashV1') {
        throw new Error('Unsupported algorithm: ' + algorithm);
      }
  
      // 拼接前缀
      const prefix = `${salt}_${expireAt}_`;
  
      try {
        // 分配栈空间
        const retptr = this.wasmInstance.__wbindgen_add_to_stack_pointer(-16);
  
        // 获取编码后的指针和长度
        const ptr0 = this.encodeString(
          challenge,
          this.wasmInstance.__wbindgen_export_0,
          this.wasmInstance.__wbindgen_export_1
        );
        const len0 = this.offset;
  
        const ptr1 = this.encodeString(
          prefix,
          this.wasmInstance.__wbindgen_export_0,
          this.wasmInstance.__wbindgen_export_1
        );
        const len1 = this.offset;
  
        // 传入正确的长度参数
        this.wasmInstance.wasm_solve(retptr, ptr0, len0, ptr1, len1, difficulty);
  
        // 获取返回结果
        const dataView = new DataView(this.wasmInstance.memory.buffer);
        const status = dataView.getInt32(retptr + 0, true);
        const value = dataView.getFloat64(retptr + 8, true);
  
        // 如果求解失败，返回 undefined
        if (status === 0)
          return undefined;
  
        return value;
  
      } finally {
        // 释放栈空间
        this.wasmInstance.__wbindgen_add_to_stack_pointer(16);
      }
    }
  
    // 初始化 WASM 模块
    async init(wasmPath) {
      const imports = { wbg: {} };
      const wasmBuffer = await fs.readFile(`./plugins/NodeUtilities-plugin/lib/${wasmPath}`);
      const { instance } = await WebAssembly.instantiate(wasmBuffer, imports);
      this.wasmInstance = instance.exports;
      return this.wasmInstance;
    }
  }
  
  // 导出类
  export default DeepSeekHash;